<?php

class InternalLibStandardCommands implements CliLibrary
{
	private static $commands = array(
		'help' => 'c_help',
		'set' => 'c_set',
		'rpn' => 'c_rpn',
		'mode' => 'c_mode',
		'ilist' => 'c_ilist',
		'copyright' => 'c_copyright',
		'version' => 'c_version',
		'about' => 'c_about',
	);

	public static function addLibrary (CliMode $mode)
	{
		$mode->addCommands(__CLASS__, self::$commands);
	}

	public static function c_help (ArgContext $args)
	{
		if ($args->hasCount(0))
		{
			$fname = 'help.txt';
		}
		else
		{
			$topic = 'help/%s.txt';
			$sub = array();

			for ($i = 0; isset($args[$i]); $i++)
			{
				$arg = $args->toString($i);
				if (!preg_match('/^[a-z0-9_]+$/', $arg))
				{
					throw new CliArgumentException(
						"Invalid help topic token '$arg'");
				}

				$subs[] = $args[$i];
			}

			$fname = vsprintf($topic, implode('/', $subs));

			if (!file_exists(CLIDIR . "/../doc/$fname"))
			{
				return "Unknown help topic";
			}
		}

		return self::getDoc($fname);
	}

	public static function c_set (ArgContext $args)
	{
		// If called with just one parameter, display the value
		if ($args->hasCount(1))
		{
			$args->requireType(0, 'string');
			return $args->getConf($args->toString(0));
		}

		$args->requireTypes('string', 'value');
		$name = $args->toString(0);
		$value = $args->toValue(1);
		$args->setConf($name, $value);

		return "Setting $name : $value";
	}

	public static function c_rpn (ArgContext $args)
	{
		$args->requireTypes('statement');
		return (string) $args[0];
	}

	public static function c_mode (ArgContext $args)
	{
		if ($args->hasCount(0))
		{
			return isset($_SESSION['mode']) ? $_SESSION['mode'] : 'std';
		}

		$args->requireTypes('string');
		$mode = strtolower($args->toString(0));

		if (!preg_match('/^[a-z]*$/', $mode))
		{
			return "Invalid mode name '$mode'";
		}

		if (!file_exists(CLIDIR . "/libraries/$mode/" . ucfirst($mode) . "ModeHandler.class.php"))
		{
			return "The mode '$mode' does not exist";
		}

		$_SESSION['mode'] = $mode;
		return "Mode has been changed to '$mode'";
	}

	public static function c_ilist (ArgContext $args)
	{
		$names = array(
			'commands' => CliMode::ID_COMMAND,
			'operators' => CliMode::ID_OPERATOR,
			'functions' => CliMode::ID_FUNCTION,
			'constants' => CliMode::ID_CONSTANT,
			'settings' => CliMode::ID_SETTING,
		);

		$mode = $args->getContext()->getMode();

		if ($args->hasType(0, 'string'))
		{
			$type = $args->toString(0);

			if (isset($names[$type]))
			{
				$identifiers = $mode->getIdentifiers($names[$type]);
			}
			else
			{
				throw new CliArgumentException(
					"Unknown identifier type '$type'");
			}
		}
		else
		{
			$identifiers = $mode->getIdentifiers();
		}

		sort($identifiers);

		return implode("\n", $identifiers);
	}

	public static function c_copyright (ArgContext $args)
	{
		return self::getDoc('copyright.txt');
	}

	public static function c_version (ArgContext $args)
	{
		return self::getDoc('version.txt');
	}

	public static function c_about (ArgContext $args)
	{
		return self::getDoc('about.txt');
	}

	private static function getDoc ($fname)
	{
		$text = file_get_contents(CLIDIR . '/../doc/' . $fname);
		$text = "\n" . trim($text) . "\n";
		return $text;
	}
}

?>